
import xmltodict
from server.pao_python.pao.service.data.mongo_db import MongoService, MongoFilter, C, N, F, as_date
from ..buss_pub.bill_manage import BillManageService, OperationType, TypeId, Status
from ..mongo_bill_service import MongoBillFilter
import uuid
import dicttoxml
from flask import abort
import hashlib
# 回调处理静态类


class OfficialAccountsCallback:
    # 处理微信公众号请求回调
    @staticmethod
    def xfy_follow_callback(request, bill_manage_server):
        if request.method == 'GET':
            # 开发者模式验证
            token = '891a1cda08e50c3e2029c2701b6a5598'
            signature = request.args.get("signature")
            timestamp = request.args.get("timestamp")
            nonce = request.args.get("nonce")
            echostr = request.args.get("echostr")
            # 校验参数
            if not all([signature, timestamp, nonce]):
                abort(400)
            # 按照微信的流程进行计算签名
            array = [token, timestamp, nonce]
            # 排序
            array.sort()
            # 拼接字符串
            tmp_str = "".join(array)
            # 进行sha1加密，得到正确的签名值
            sign = hashlib.sha1(tmp_str.encode("utf-8")).hexdigest()
            if signature != sign:
                abort(403)
            else:
                return echostr
        else:
            try:
                call_info = xmltodict.parse(request.data)["xml"]
                fromUserName = call_info['FromUserName']
                toUserName = call_info['ToUserName']
                createTime = call_info['CreateTime']
                eventKey = call_info['EventKey']
                msgType = call_info['MsgType']
                eventType = call_info['Event']

                if VxMessageUtil.MSGTYPE_EVENT == msgType:
                    if VxMessageUtil.MESSAGE_SUBSCIBE == eventType:
                        # 处理订阅事件
                        message = VxMessageUtil.subscribeForText(bill_manage_server,
                                                                 toUserName, fromUserName, createTime, eventKey)
                    elif VxMessageUtil.MESSAGE_UNSUBSCIBE == eventType:
                        # 处理取消订阅事件
                        message = VxMessageUtil.unsubscribe(bill_manage_server,
                                                            toUserName, fromUserName, createTime, eventKey)
            except Exception as e:
                print(e)
            # out.close()
            return dicttoxml.dicttoxml({'retcode': 0, 'reason': message}, custom_root='response', attr_type=False).decode('utf-8')


class VxMessageUtil:
    ''' 消息枚举类 '''
    MSGTYPE_EVENT = "event"
    MESSAGE_SUBSCIBE = "subscribe"
    MESSAGE_UNSUBSCIBE = "unsubscribe"
    MESSAGE_TEXT = "text"

    # 响应订阅事件--回复文本消息
    @staticmethod
    def subscribeForText(bill_manage_server, toUserName, fromUserName, createTime, eventKey):
        params = eventKey.split("_")
        organization_id = ''
        if (len(params) == 2):
            organization_id = params[1]
        # 查询关注人是否已有关注明细，已关注过则不处理，没关注过则新增数据
        _filter = MongoBillFilter()
        _filter.match_bill((C('from_user_name') == fromUserName))\
            .sort({'create_date': -1})\
            .project({"_id": 0})
        res = bill_manage_server.query(_filter, "PT_Wx_Follow_Detail")
        if len(res) == 0:
            detail = {'id': str(uuid.uuid1()), 'to_user_name': toUserName, 'from_user_name': fromUserName,
                      'create_date': createTime, 'organization_id': organization_id, 'state': VxMessageUtil.MESSAGE_SUBSCIBE}
            bill_id = bill_manage_server.add_bill(
                OperationType.add.value, TypeId.activity.value, [detail], ['PT_Wx_Follow_Detail'])
            # 查询汇总表是否存在汇总信息，存在则更新关注数量+1，不存在则新增数据
            _filter = MongoBillFilter()
            _filter.match_bill((C('organization_id') == organization_id))\
                .sort({'create_date': -1})\
                .project({"_id": 0})
            res_total = bill_manage_server.query(_filter, "PT_Wx_Follow")
            if len(res_total) > 0:
                total = res_total[0]
                total['follow_quantity'] = total['follow_quantity'] + 1
                bill_id = bill_manage_server.add_bill(
                    OperationType.update.value, TypeId.activity.value, [total], ['PT_Wx_Follow'])
            else:
                total = {'id': str(
                    uuid.uuid1()), 'organization_id': organization_id, 'follow_quantity': 1}
                bill_id = bill_manage_server.add_bill(
                    OperationType.add.value, TypeId.activity.value, [total], ['PT_Wx_Follow'])
        if bill_id:
            return 'success'

        # 响应取消订阅事件

    @staticmethod
    def unsubscribe(bill_manage_server, toUserName, fromUserName, createTime, eventKey):
        # TODO 可以进行取关后的其他后续业务处理
        # System.out.println("用户：" + fromUserName + "取消关注~")
        return 'success'
